/*
 * Copyright 2014 alexpad@gmail.com.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package alexpad.karaokarc;

import alexpad.karaokarc.midi.*;
import java.io.*;
import java.util.*;
import org.apache.commons.lang3.SerializationUtils;

/**
 *
 * @author alexpad@gmail.com
 */
public class MidiArchive implements java.io.Serializable {
	
	private static final long serialVersionUID = 1L;
	
	private Map<String, MidiSongInfo> infos;
	private long archiveDirLastModified;
	private File archiveDir;

	protected MidiArchive() {}
	
	public static MidiArchive load(File file) throws IOException{
		if(!file.isFile()) return null;
		return (MidiArchive) SerializationUtils.deserialize(new FileInputStream(file));
	}
	
	public void save(File file) {
		archiveDirLastModified = getArchiveDir().lastModified();
		try{
			SerializationUtils.serialize(this, new FileOutputStream(file));
		}
		catch(IOException ex){
			throw new RuntimeException(ex);
		}
	}
	
	/**
	 * Crea un nuovo MidiArchive leggendo i file presenti nella cartella archiveDir.
	 * @param archiveDir
	 * @return 
	 */
	public static MidiArchive create(File archiveDir) {
		File[] midiFiles = MidiUtil.listMidiFiles(archiveDir);
		Map<String, MidiSongInfo> infos = new HashMap<>(midiFiles.length);
		int count = 0;
		MidiSongInfo songInfo;
		for (File file : midiFiles) {
			songInfo = new MidiSongInfo(file);
			infos.put(songInfo.getFileHash(), songInfo);
			count++;
			if(count%25==0) System.out.println("processati " + count);
		}
		return MidiArchive.create(infos, archiveDir);
	}
	
	/**
	 * Crea un nuovo MidiArchive come copia di sourceMidiArchive.
	 * @param sourceMidiArchive
	 * @return 
	 */
	public static MidiArchive copy(MidiArchive sourceMidiArchive) {
		MidiArchive midiArchive = create(sourceMidiArchive.getArchiveDir());
		MidiSongInfo newInfo;
		for(MidiSongInfo oldInfo : sourceMidiArchive.getInfosAsList()){
			newInfo = midiArchive.getInfo(oldInfo.getFileHash());
			if(newInfo!=null){
				newInfo.copySongInfo(oldInfo);
			}
		}
		return midiArchive;
	}
	
	private static MidiArchive create(Map<String, MidiSongInfo> infos, File archiveDir){
		if(!archiveDir.isDirectory()){
			throw new IllegalArgumentException("la cartella '"+archiveDir+"' non esiste");
		}
		MidiArchive item = new MidiArchive();
		item.infos = infos;
		item.archiveDir = archiveDir;
		item.archiveDirLastModified = archiveDir.lastModified();
		return item;
	}

	public Map<String, MidiSongInfo> getInfos() {
		return infos;
	}

	public List<MidiSongInfo> getInfosAsList() {
		List<MidiSongInfo> list = new ArrayList<MidiSongInfo>(infos.values());
		Collections.sort(list);
		return list;
	}
	
	public boolean isChanged(){
		return archiveDirLastModified != getArchiveDir().lastModified();
	}

	public MidiSongInfo getInfo(String fileHash) {
		return infos.get(fileHash);
	}

	public File getArchiveDir() {
		return archiveDir;
	}
	
}
